<?php
namespace Common\Model;

class ZoneModel extends Model {
    protected $tableName = 'zone';

    /**
     * buildSearchExpr 
     * 组装查询条件
     * 
     * @param mixed $d  查询数据，一般来源于$_GET或$_POST
     * @param mixed $field  可查询的字段对照表，其结构为array(array('表单项目名称' => '数据库字段名称'))
     * @access public
     * @return void 返回值为数组，参见方法内部注释
     */
    public function buildSearchExpr($d, $field = NULL) {
        $expr = array();
        $dao  = array();
        $sortExpr = 'id DESC';
		
        /**
         * 下标为表单中的项目名称，值为数据库中表的字段名称 
         */

        if(empty($field)) {
            $field = array(
                'uid'            => 'uid',
                'user_name'      => 'user_name',
                'plan_type'      => 'plan_type',
                'id'        	 => 'id',
                'zone_width'     => 'zone_width',
                'zone_height'    => 'zone_height',
                'zone_type'      => 'zone_type',
                'zone_auto_view' => 'zone_auto_view',
            );
        }
		
        foreach($field as $k => $v) {
            $val = isset($d[$k]) ? trim($d[$k]) : '';
            if(strlen($val) < 1) {
                continue;
           }

            switch($k) {
                case 'user_name' :
                    $expr['user_name'] = array('EXP', "LIKE '%{$val}%'");
                    break;

                default:
                    $expr[$v] = $d[$k];
            }

            $dao[$k] = $d[$k];
        }

        /**
         * 处理多个查询项目合并到一起，然后只能选一项查询的情况
         * 保存到$dao中，用于回填至查询表单
         */
        foreach($d as $k => $v) {
            if(substr($k, 0, 12) == 'search_item_') {
                $dao[$k] = $v;
            }
        }
        /**
         * 因为部分查询会涉及到视图，所以需要在下面指定完整的可排序字段
         */
        $sortField = array('uid', 'plan_type', 'zone_type', 'id', 'size', 'user_name');

        if(!empty($d['sort']) && in_array($d['sort'], $sortField)) {
            $sortdir = empty($d['sortdir'])                     ? 'DESC'   : strtoupper($d['sortdir']);
            $sortdir = in_array($sortdir, array('DESC', 'ASC')) ? $sortdir : 'DESC';

            if($d['sort'] == 'size') {
                $sort     = 'size';
                $sortExpr = "zone_width {$sortdir}, zone_height {$sortdir}";
            } else {
                $sort     = $d['sort'];
                $sortExpr = "{$sort} {$sortdir}";
            }

            $dao['sort']    = $sort;
            $dao['sortdir'] = $sortdir;
        }
		
		
		
        return array(
            'expr' => $expr,            //ThinkPHP查询条件表达式
            'sort' => $sortExpr,        //排序表达式
            'json' => json_encode($dao) //用于回填至查询表单的数据
        );
    }

    public function save2($d) {
        $action = '';
        $id     = empty($d['id']) ? 0 : (int)$d['id'];

        if(empty($d['name'])) {
            throw new \Exception('请指定广告位名称');
        }

        $d['name'] = strip_tags($d['name']);
        $uid       = empty($d['uid']) ? '' : $d['uid'];

        if (empty($id)) {
            $action = 'add';

            if(empty($uid)) {
                throw new \Exception('没有站长编号，不能增加广告位');
            }

            if (!$siterRecord = D2('Siter')->where(['id' => $uid])->find()) {
                throw new \Exception('没有找到站长数据');
            }

            $d['create_time'] = date('Y-m-d H:i:s');
        } else {
            $action = 'save';

            if(!$zoneRecord = $this->where(['id' => $id])->find()) {
                throw new \Exception('没有找到广告位信息，无法保存');
            }

            $uid = $zoneRecord['uid'];
        }

        $this->checkNameExists($d['name'], $uid, $id);

        $d['type'] = strtolower($d['type']);

        try {
            $d['opts'] = $this->buildOpts($d);
        } catch(\Exception $e) {
            throw new \Exception($e->getMessage());
        }

        if (!$r = $this->$action($d)) {
            return $r;
        }

        $zoneId = $action == 'add' ? $r : $d['id'];

        try {
            $args = [
                'a'  => ($action == 'add' ? 'add' : 'modify'),
                'id' => $zoneId,
            ];
            cacheApi('zone', $args);
        } catch(\Exception $e) {
            throw new \Exception($e->getMessage());
        }

        return $r;
    }

    /**
     * checkZoneName
     * 检测广告位名称是否存在
     *
     * 广告位名称以站长为单位检测，不同站长可以有相同的广告位名称
     *
     * @param mixed $zoneName
     * @param mixed $uid
     * @param mixed $excludeId
     * @return void
     */
    public function checkNameExists($name, $uid, $excludeId = null) {
        $uid = (int)$uid;

        if (empty($uid)) {
            throw new \Exception('请指定站长编号');
        }

        $expr = array(
            'name' => $name,
            'uid'  => $uid,
        );

        $id = (int)$excludeId;

        if (!empty($id)) {
            $expr['id'] = array('NEQ', $id);
        }

        return $this->field('id')->where($expr)->find();
    }

    /**
     * del
     *
     * @param mixed $id
     * @return void
     */
    public function del($id) {
        $id = (int)$id;

        if (!$record = $this->where(['id' => $id])->find()) {
            return true;
        }

        $expr = array(
            'day' => date('Y-m-d'),
            'uid' => $record['uid'],
            'id'  => $id,
        );
        $zoneStatsModel = D('ZoneStats');

        try {
            if ($zoneStatsModel->where($expr)->find()) {
                throw new \Exception('此广告位今天已经有计费数据，无法删除');
            }
        } catch(\Exception $e) {
        }

        $expr = [            
            'id' => $id,
        ];

        $r = $this->where($expr)->delete();

        try {
            cacheApi('zone', ['a' => 'del', 'id' => $id]);
        } catch(\Exception $e) {
            throw new \Exception($e->getMessage());
        }

        return $r;
    }

    protected function _before_update(&$data, &$options) {
        if(!isset($data[$this->getPk()])) {
            return false;
        }

        $loginUser = C('RUN_LOGIN_USER');

        /**
         * 检测被保存数据是否属于站长客服的
         */
        if(0 && isSiterService($loginUser['type'])) {
            $m = D2('VZone');
            $key = $this->getPk();
            $expr = array(
                $key => $data[$key],
            );

            if(!$r = $m->where($expr)->find()) {
                return false;
            }
        }

        if(isset($options['where']) && !array_key_exists($this->getPk(), $options['where'])) {
            $options['where'][$this->getPk()] = $data[$this->getPk()];
        }

        return true;
    }

    protected function _options_filter(&$options) {
        if(!$loginUser = C('RUN_LOGIN_USER')) {
            exit('NO LOGIN');
        }

        if($loginUser['type'] == 1) {
            $options['where'] = isset($options['where']) ? $options['where'] : array();
            $options['where']['uid'] = $loginUser['id'];

            return true;
        }
    }

    public function buildOpts($d) {
        $id = empty($d['id']) ? 0 : (int)$d['id'];
        $r  = [];

        if ($id) {
            if (!$tmp = $this->field('opts')->where(['id' => $id])->find()) {
                throw new \Exception('没有找到广告位数据');
            }

            $r = ($t = json_decode($tmp)) ? $t : [];
        }

        switch ($d['type']) {
            case 'zl' :
                $r = array_merge($r, $this->buildIdsOpts($d));
                break;
        }

        return json_encode($r);
    }

    /**
     * buildIdsOpts
     * 组装自选广告选项
     *
     * 直链只允许选择一条广告
     *
     * @param mixed $d
     * @return void
     */
    public function buildIdsOpts($d) {
        $adId = empty($d['ad_id']) ? 0 : (int)$d['ad_id'];

        if (empty($adId)) {
            throw new \Exception('请选择广告');  
        }

        $adModel = D('Ad');

        if (!$adRecord = $adModel->where(['id' => $adId])->find()) {
            throw new \Exception('没有找到广告');
        }

        if (!$adModel->isActive($adRecord['status'])) {
            throw new \Exception('选择的广告不是投放中');
        }

        $planModel = D('Plan');

        if (!$planRecord = $planModel->where(['id' => $adRecord['plan_id']])->find()) {
            throw new \Exception('未找到广告计划');
        }

        if (!$planModel->isActive($planRecord['status'])) {
            throw new \Exception('广告广告不是投放中');
        }

        return [
            'ids' => [[
                'plan_id' => $adRecord['plan_id'],  //加入plan_id是便于编辑广告位时快速定位到广告计划
                'ad_id'   => $adRecord['id'],
            ]]
        ];
    }

    public function parseOpts($d) {
        $opts = empty($d['opts']) ? '' : $d['opts'];

        if (empty($opts)) {
            return '';
        }

        return json_decode($opts, true);
    }

}
